
typedef struct __S_Layer S_Layer;

struct __S_Layer {
    S_Layer*		m_UpLayer;
	S_Layer*		m_DownLayer;

	uint m_Layer_ID;

	uint			m_InNum;
	uint			m_OutNum;

	//-----------------Node------------------
	float**		m_Weigths;		//m_输入数量*m_输出数量
    float**     m_梯度;

	float*		m_Err;
    float*		m_Out;
	float*      m_Bias;

};


void f_计算隐藏层节点误差(S_Layer* Layers);


__kernel void f_aiCalc_NodeOutLayerErr(__global S_Layer* Layers, __global float* checkValue) {
    size_t groupID = get_global_linear_id();

    float outVar = Layers->m_Out[groupID];
    Layers->m_Err[groupID] = outVar * (1.0f-outVar) * (checkValue[groupID] - outVar);
    //printf("m_Err %v3f \n", (float3)(Layers->m_Err[groupID], outVar, checkValue[groupID]) );
    
    if(groupID==0 && Layers->m_UpLayer){
        
        ndrange_t ndrange1 = ndrange_1D(Layers->m_InNum); 
        
        void(^func_SamplingBlock)(void) = ^{ f_计算隐藏层节点误差(Layers->m_UpLayer); } ;
        int err_ret = enqueue_kernel(get_default_queue(), CLK_ENQUEUE_FLAGS_WAIT_KERNEL, ndrange1, func_SamplingBlock);

    }
}



void f_计算隐藏层节点误差(S_Layer* Layers){
    size_t groupID = get_global_linear_id();

    uint 下游节点数量 = Layers->m_DownLayer->m_OutNum;
    float* downStremErr = Layers->m_DownLayer->m_Err;
    //float* downStremWeigths = Layers->m_Weigths;
    float 下游误差 = 0.0;

    for(uint i=0; i<下游节点数量; ++i){
        下游误差 += downStremErr[i] * Layers->m_DownLayer->m_Weigths[i][groupID];
        ///printf("m_Err %v3f \n", (float3)(下游误差, downStremErr[i], Layers->m_DownLayer->m_Weigths[i][groupID]) );
    }
    float outVar = Layers->m_Out[groupID];
    Layers->m_Err[groupID] = outVar * (1.0f-outVar) * 下游误差;
    //printf("m_Err %v3f \n", (float3)(Layers->m_Err[groupID], outVar, 下游误差) );

    if(groupID==0){
        for(uint i=0; i<下游节点数量; ++i){
            下游误差 += downStremErr[ Layers->m_DownLayer->m_OutNum ]  *  Layers->m_DownLayer->m_Weigths[i][Layers->m_DownLayer->m_OutNum];
        }
        float outVar = Layers->m_Bias[Layers->m_OutNum-1];
        Layers->m_Err[Layers->m_OutNum] = outVar * (1.0f-outVar) * 下游误差;
        //printf("m_Err %v3f \n", (float3)(Layers->m_Err[Layers->m_OutNum], outVar, 下游误差) );
    }

    //printf("Layers->m_InNum %f \n", Layers->m_Err[groupID]);
    
}



